/*******************************************************************************
 * @file Philosoph.h
 * Definition of the CPhilosoph class.
 * 
 * @package Dining.
 * 
 * @author mk
 * @date 03/01/2008 13:50:21
 * @version 0.1
 ******************************************************************************/
 
#ifndef __PHILOSOPH_H_INCLUDED__
#define __PHILOSOPH_H_INCLUDED__

#ifndef __MSVC_COMPILER_RECOGNIZES_CORRECT_FORWARD_DECLARATION__
#include "Spoon.h"
#endif

/** @brief Project related classes are scoped by this namespace. */
namespace Dining
{
#ifdef __MSVC_COMPILER_RECOGNIZES_CORRECT_FORWARD_DECLARATION__
	class CSpoon;
#endif
	class CFood;
	
	/** @brief Class for defining a philosopher. */
	class CPhilosoph
	{
	public:
		/** Default constructor not allowed to be used on conversions. */
		CPhilosoph(const unsigned int anId, 
			CSpoon& aLeft,
			CSpoon& aRight,
			volatile CFood& aFood);
				   
		/** Destructor */
		~CPhilosoph();
		
		/**
		 * Called when the philosoph instance is passed to a boost::thread. 
		 * This operator can be seen as the "awake" call.
		 */		 
		void operator()();

		/** Get the amount of consumed portions. */
		unsigned int GetConsumed() const { return m_Consumed; }

		/** Get the id of the philosoph instance. */
		unsigned int GetId() const { return m_Id; }
		
	private:
		/** Asignment operator made private for disallowing copy assignment. */
		CPhilosoph& operator= (const CPhilosoph& /*aPhil*/);

		/** Copy constructor made private for disallowing copy construction. */
		CPhilosoph(const CPhilosoph& /*aPhil*/);
	
		/** Called for setting the philosopher into "eating" state. */
		void Eat();
		
		/** Called for setting the philosopher into "thinking" state. */
		void Think();
		
		const unsigned int m_Id;		///< has an id
		CSpoon& m_Left;					///< uses a spoon (left)
		CSpoon& m_Right;				///< uses a spoon (right)
		volatile CFood& m_Food;			///< uses the food bowl
		unsigned int m_Consumed;		///< has a counter for counting the portions		
	};
}

#endif /*__PHILOSOPH_H_INCLUDED__*/
